require 'sinatra'
require 'sinatra/activerecord'
require 'active_record'
require '../../db/database.rb'
require '../model.rb'
require '../enums.rb'
require '../conferencia.rb'
require '../IngresarArchivo.rb'
require '../charla.rb'
require '../usuario.rb'
require '../Mensajeria.rb'
require 'Haml'
require "dm-core"
#for using auto_migrate!
require "dm-migrations"
require "digest/sha1"
require 'bundler'
Bundler.require

enable :sessions
set :protection, except: :session_hijacking

before do
  pass if %w[login nuevoUsuario crearUsuario].include? request.path_info.split('/')[1]
  unless session[:id_usuario]
    redirect to('/login')
  end
end

before do
  content_type :html, 'charset' => 'utf-8'
end

get '/listaConferencia' do
  @list = Conferencia.all
  @usuario = Usuario.find(session[:id_usuario])
  erb :conferencia_lista
end

get '/crearConferencia' do  
  @usuariosGuardados = {}
  @usuariosDisponibles = Usuario.all
  
  erb :conferencia_nueva
end

post '/crearConferencia' do
  nombreConf = params[:nombre]
  adminSeleccionados = params[:SelectRight]
  
  conf = Conferencia.new
  conf.nombre = nombreConf
  conf.estado = EstadoConferencia::NUEVA
  
  conf.valid? 
  
  if conf.errors["nombre"].blank? and !adminSeleccionados.nil?
    conf.save(:validate => false)
      
    adminSeleccionados.each do |idUsuario|
      admin = AdministradoresConferencia.new
      admin.usuario = Usuario.find(idUsuario)
      admin.conferencia = conf
      admin.save
      
      nombreApellidoUsuario = admin.usuario.nombre + admin.usuario.apellido
      
      Mensajeria.EnvioMensajeria(admin.usuario.email, "Conferencia creada", Mensajeria.conferenciaCreada(nombreApellidoUsuario, conf.nombre))
    end 
    redirect to('/listaConferencia') 
  else
    @message = ""
    conf.errors["nombre"].each do |e|
      @message= @message + e + "<br />"
    end
    @message= @message + "* Por favor ingrese al menos un usuario administrador" + "<br />" if adminSeleccionados.nil? 
    
    @usuariosDisponibles = Usuario.usuariosDisponibles(adminSeleccionados)
    @usuariosGuardados = Usuario.usuariosGuardados(adminSeleccionados)
    erb :conferencia_nueva
  end
end

get '/editarConferencia/:idConferencia' do
  @conferencia = Conferencia.find(params[:idConferencia])
  erb :editar_conferencia
end

post '/editarConferencia/:idConferencia' do
  descripcionConf = params[:descripcion]
  fechaInicioConf = params[:fechaInicio]
  fechaFinConf = params[:fechaFin]
  lugar = params[:lugar]
  tiempoLimite = params[:tiempoLimite]
  
  archivoImagen = params[:imagen] 
    
  conf= Conferencia.find(params[:idConferencia])
  conf.descripcion = descripcionConf
  conf.fechaInicio = fechaInicioConf
  conf.fechaFin = fechaFinConf
  conf.lugar = lugar
  conf.tiempoLimite = tiempoLimite
  
  @conferencia = conf
  
  if conf.valid? && IngresarArchivo.sePuedeIngresarArchivo?(archivoImagen)
    conf.fechaInicio = Date.parse(fechaInicioConf)
    conf.fechaFin = Date.parse(fechaFinConf)
    conf.save
    
    IngresarArchivo.cargarArchivo(archivoImagen, "public/logos", conf)
    
    redirect to('/listaConferencia') 
  else
    @message = ""
    conf.errors.messages.each do |e|
      @message= @message + e[1][0] + "<br />"
    end 
    erb :editar_conferencia
  end
end

get '/crearCharla/:idConferencia' do
  @conferencia = Conferencia.find(params[:idConferencia])
  erb :charla_cargar
end

post '/crearCharla/:idConferencia' do
  idConferencia = params[:idConferencia]
  titulo = params[:titulo]
  descripcion = params[:abstract]
  
  @conferencia = Conferencia.find(idConferencia)
  @usuario = Usuario.find(session[:id_usuario])
  
  charla = Charla.new
  charla.conferencia = @conferencia
  charla.titulo = titulo
  charla.abstract = descripcion
  charla.estado = EstadoCharla::PROPUESTA
  charla.usuario = @usuario
  
  if charla.valid?
    charla.save
    redirect to('/listaConferencia') 
  else
    @message = ""
    charla.errors.messages.each do |e|
      @message= @message + e[1][0] + "<br />"
    end 
    erb :charla_cargar
  end
end

get '/verCharlas/:idConferencia' do
  @list = Charla.ordenarCharlas(params[:idConferencia])
  @conferencia = Conferencia.find(params[:idConferencia])
  erb :ver_charlas
end

get '/verCharlasPublicadas/:idConferencia' do
  @list = Charla.filtrarCharlasPorEstado(params[:idConferencia], EstadoCharla::ACEPTADA)
  @conferencia = Conferencia.find(params[:idConferencia])
  erb :ver_charlas_publicadas
end

get '/asignarCharla/:idCharla' do
  @charla = Charla.find(params[:idCharla])
  
  asignacionesCharla= Asignacion.where("charla_id = ?", params[:idCharla]) 
  @usuariosGuardados = asignacionesCharla.collect{ |asignacion| asignacion.usuario }
  
  idsUsuarios = @usuariosGuardados.collect{ |usuario| usuario.id }
  @usuariosDisponibles = (Usuario.all).select{ |usuario| ! idsUsuarios.include?(usuario.id.to_i)}
  
  erb :asignar_charla_reviewers  
end

post '/asignarCharla' do   
  @charla = Charla.find(params[:idCharla])  
  asignacionesGuardadas = Asignacion.where("charla_id = ?", params[:idCharla])
  
  usuariosGuardados = asignacionesGuardadas.collect{ |asignacion| asignacion.usuario.id }  
  usuariosSeleccionados = params[:SelectRight]
  
  if !usuariosSeleccionados.nil?
    Asignacion.where(["charla_id = ? and usuario_id not in (?)", params[:idCharla], usuariosSeleccionados]).destroy_all
    nuevosUsuarios = (usuariosSeleccionados.select{ |id| ! usuariosGuardados.include?(id.to_i)})
  
    nuevosUsuarios.each do |idUsuario|
      asignacion = Asignacion.new
      asignacion.charla = @charla
      asignacion.usuario = Usuario.find(idUsuario)
      asignacion.save
      
      nombreApellidoUsuario = asignacion.usuario.nombre + asignacion.usuario.apellido
      
      Mensajeria.EnvioMensajeria(asignacion.usuario.email, "Evaluador charla" + @charla.titulo, Mensajeria.evaluadorElegido(nombreApellidoUsuario, @charla))
    end
  
    redirect to('/verCharlas/'+ @charla.conferencia_id.to_s)
  else
    @message = "* Por favor, asigne algun evaluador a la charla."
    @usuariosDisponibles = (Usuario.all) 
    @usuariosGuardados = Array.new 
    erb :asignar_charla_reviewers
  end
end

get '/charlaAEvaluar/:idCharla' do
  @charla = Charla.find(params[:idCharla])
  erb :evaluar_charla
end

post '/evaluarCharla/:idCharla' do
  charla = Charla.find(params[:idCharla])
  @charla = charla
  @usuario = Usuario.find(session[:id_usuario])
  
  resumen = params[:resumen]
  comentario = params[:comentario]
  estado = params[:radioEval]
  
  evaluacion = Evaluacion.new
  evaluacion.resumen = resumen
  evaluacion.comentario = comentario
  evaluacion.estado = if (estado.to_i==1) then EstadoEvaluacion::APROBADA else EstadoEvaluacion::DESAPROBADA end
  evaluacion.charla = @charla
  evaluacion.usuario = @usuario

  cantidadEvaluadores = Asignacion.cantidadEvaluadores(params[:idCharla])
  
  if evaluacion.valid?
    evaluacion.save
    
    if (Evaluacion.where("charla_id = ?", params[:idCharla]).length == cantidadEvaluadores)
      charla.estado= EstadoCharla::EVALUADA
      charla.save
    elsif (Evaluacion.where("charla_id = ?", params[:idCharla]).length < cantidadEvaluadores && @charla.estado== EstadoCharla::PROPUESTA)
      charla.estado= EstadoCharla::ENEVALUACION
      charla.save
    end
    
    redirect to('/verCharlas/'+ @charla.conferencia_id.to_s) 
  else
    @message = ""
    evaluacion.errors.messages.each do |e|
      @message= @message + e[1][0] + "<br />"
    end 
    erb :evaluar_charla
  end
end

get '/vistaEvaluaciones/:idCharla' do
  @charla = Charla.find(params[:idCharla])
  @list = Evaluacion.where("charla_id = ?", params[:idCharla])
  
  @evaluacionesAprobadas = @list.where("estado = ?", EstadoEvaluacion::APROBADA)
  @evaluacionesRechazadas = @list.where("estado = ?", EstadoEvaluacion::DESAPROBADA)
  
  erb :ver_evaluaciones
end

get '/aceptarCharla/:idCharla' do
  charla = Charla.find(params[:idCharla])
  
  charla.estado = EstadoCharla::ACEPTADA
  charla.save
  
  Mensajeria.EnvioMensajeria(charla.usuario.email, "Su charla " + c.titulo + " ha sido aceptada", Mensajeria.charlaEvaluada(c))
  
  redirect to('/verCharlas/'+ charla.conferencia_id.to_s)
end

get '/rechazarCharla/:idCharla' do
  charla = Charla.find(params[:idCharla])

  charla.estado = EstadoCharla::RECHAZADA
  charla.save
  
  Mensajeria.EnvioMensajeria(charla.usuario.email, "Su charla " + c.titulo + " ha sido rechazada", Mensajeria.charlaEvaluada(c))
  
  redirect to('/verCharlas/'+ charla.conferencia_id.to_s)
end

get '/login' do
  if (session[:id_usuario].nil?)
    erb :login
  else
    redirect to('/listaConferencia') 
  end
end

post '/login' do
  email = params[:email]
  password = params[:password]
  
  validationPass = password.length >= 6 && password.length<=20 
  
  @message= ""
  
  @message= @message + "* Ingrese el usuario." + "<br />" if email.empty?
  @message= @message + "* Ingrese su clave." + "<br />" if password.empty?
  @message= @message + "* Por favor ingrese una clave valida." + "<br />" if ! password.empty? && !validationPass
  
  usuarios = Usuario.where("email = ?", email)
  
  usuario = usuarios.first
  
  @message= @message + "* Datos de registro invalidos." + "<br />" if !email.empty? && !password.empty? && (usuario.nil? || usuario.passw != password)

  if (!usuario.nil? && usuario.passw == password)
    session[:id_usuario] = usuario.id
    session[:email_usuario] = usuario.email  
    redirect to('/listaConferencia') 
  else
    erb :login
  end
end

get '/logout' do
  session.clear
  redirect to('/login')
end

get '/nuevoUsuario' do
  erb :usuario_nuevo
end

post '/crearUsuario' do 
  name = params[:nombre]
  surname = params[:apellido]
  email = params[:email]
  password = params[:password]
  titulo = params[:titulo]
  nombreEmpresa = params[:nombreEmpresa]
  webEmpresa = params[:sitioWebEmpresa] 
  resumen = params[:resumen] 
  
  archivoImagen = params[:imagen]
    
  user = Usuario.new
  user.nombre = name
  user.apellido = surname
  user.email = email
  user.passw = password
  user.esSuperAdmin = false
  user.titulo = titulo
  user.nombreEmpresa = nombreEmpresa
  user.sitioWebEmpresa = webEmpresa
  user.resumen = resumen
  
  formatosAceptados = [".png", ".jpg", ".bmp", ".gif"]
  
  if user.valid? && IngresarArchivo.sePuedeIngresarArchivo?(archivoImagen)
    user.save
    
    IngresarArchivo.cargarArchivo(archivoImagen, "public/avatars", user)
    
    erb :login
  else
    @message = ""

    user.errors.messages.each do |e|
      @message= @message + e[1][0] + "<br />"
    end 
    erb :usuario_nuevo
  end
end

get '/buscarCharla' do
  letraUsuario = params[:userNotSelected]
  @usuariosDisponibles = Usuario.where("nombre like %?% or apellido like %?%", letraUsuario, letraUsuario)
end

get '/cerrarEvaluacion/:idConferencia' do
  idConferencia = params[:idConferencia]
  conferencia = Conferencia.find(idConferencia)
  
  charlasPendientes = Conferencia.charlasPendientesDeConferencia(idConferencia)
  
  charlasPendientes.each do |c|
    c.estado = EstadoCharla::DESCARTADA
    c.save
    
    Mensajeria.EnvioMensajeria(c.usuario.email, "Su charla " + c.titulo + " ha sido descartada", Mensajeria.charlaEvaluada(c))
  end
  
  conferencia.estado = EstadoConferencia::CONVOCATORIACERRADA
  conferencia.save
  
  redirect to('/verCharlas/'+ idConferencia)
end

get '/planificacion/:idConferencia' do
  idConferencia = params[:idConferencia]
  @conferencia = Conferencia.find(idConferencia)
  @charlasAceptadasPendientePlanificacion = Charla.charlasAceptadasPendientesPlanificacion(idConferencia)
  
  @charlasAceptadasConPlanificacion = Hash.new
  @conferencia.diasDeDuracion.times do |d|
    @charlasAceptadasConPlanificacion[d] = Charla.charlasAceptadasPlanificadas(idConferencia, @conferencia.fechaInicio + d)
  end
  erb :planificacion
end

post '/agendar/:numeroDia' do
  numeroDiaCharla = params[:numeroDia] 
  horarioInicio = params[:fechaInicio]
  horarioFin = params[:fechaFin]
  charlaSeleccionada = params[:SelectLeft]
  
  idConferencia = params[:idConferencia]
  @conferencia = Conferencia.find(idConferencia)
  @charlasAceptadasPendientePlanificacion = Charla.charlasAceptadasPendientesPlanificacion(idConferencia)
  @charlasAceptadasConPlanificacion = Hash.new
  @conferencia.diasDeDuracion.times do |d|
    @charlasAceptadasConPlanificacion[d] = Charla.charlasAceptadasPlanificadas(idConferencia, @conferencia.fechaInicio + d)
  end
  
  if !charlaSeleccionada.nil?
    charla = Charla.find(charlaSeleccionada.to_i)
  end
  
  if (!charla.nil? && !horarioInicio.empty? && !horarioFin.empty? && charla.valid?)
    charla.horarioInicio = Charla.convertirHourStringToMinutes(horarioInicio)
    charla.horarioFin = Charla.convertirHourStringToMinutes(horarioFin)
    
    charla.fechaElegida = @conferencia.fechaInicio + numeroDiaCharla.to_i
    horarioFinEsMayorAHorarioInicio = charla.horarioFin > charla.horarioInicio

    charla.save
    redirect to('/planificacion/' + charla.conferencia_id.to_s) 
  else 
    @message = ""
    @message = @message + "* Por favor, seleccione una charla." + "<br />" if charlaSeleccionada.nil?
    @message = @message + "* Por favor, ingrese un horario." + "<br />" if (horarioInicio.empty? || horarioFin.empty?)  
      
    if (!charla.nil?)
      charla.errors.messages.each do |e|
        @message= @message + e[1][0] + "<br />"
      end 
    end
      
    erb :planificacion
  end
end

post '/desagendar/:idCharla' do
  charla = Charla.find(params[:idCharla])
  charla.horarioInicio = nil
  charla.horarioFin = nil
  charla.fechaElegida = nil
  
  if charla.valid?
    charla.save
    redirect to('/planificacion/' + charla.conferencia_id.to_s)   
  end
end

get '/cerrarPlanificacion/:idConferencia' do
  idConferencia = params[:idConferencia]
  conferencia = Conferencia.find(idConferencia)
  
  conferencia.estado = EstadoConferencia::PUBLICADA
    
  if conferencia.valid?
    conferencia.save
    
   #charlasAceptadasPlanificadas do |charla|
   #   Mensajeria.EnvioMensajeria(charla.usuario.email, "Cronograma charla " + charla.titulo, Mensajeria.agenda(charla))
    #  Mensajeria.EnvioMensajeria(charla.moderador.email, "Moderador charla  " + charla.titulo, Mensajeria.moderadorElegido(charla))
    #end
    
    redirect to('/listaConferencia') 
  else
    @message = "Ha ocurrido un error vuelve a intentarlo"
    erb :planificacion
  end 
end

get '/cronograma/:idConferencia' do
  idConferencia = params[:idConferencia]        
  @conferencia = Conferencia.find(idConferencia)
  
  @charlasAceptadasConPlanificacion = Hash.new                                                                             
  @conferencia.diasDeDuracion.times do |d|                                                                                             
    @charlasAceptadasConPlanificacion[d] = Charla.charlasAceptadasPlanificadas(idConferencia, @conferencia.fechaInicio + d)
  end 
  erb :agenda 
end

get '/asignarModerador/:idCharla' do
  @charla = Charla.find(params[:idCharla])
  
  @usuariosDisponibles = Usuario.all
  
  erb :asignar_moderador
end

post '/asignarModeradorCharla/:idCharla' do
  @charla = Charla.find(params[:idCharla])
 
  usuarioAGuardar = params[:SelectRight] 
  
  if !usuarioAGuardar.nil? 
    idUsuario = usuarioAGuardar
    charla = Charla.find(params[:idCharla])
    charla.moderador = Usuario.find(idUsuario.to_i)
    charla.save
    
    redirect to('/verCharlas/'+ @charla.conferencia_id.to_s)
  else
    @message = "* Por favor, asigne un moderador a la charla."
    @usuariosDisponibles = (Usuario.all) 
    @usuariosGuardados = Array.new 
    erb :asignar_moderador
  end
end                                                                                                          